Post

Replies

Boosts

Views

Activity

How to animate NavigationSplitView's detailView column.
Having a traditional 'NavigationSplitView' setup, I am looking for a way to animate it the same as the sidebarView, where there is a button to toggle and it animates by sliding out from the right side of the view, however the closest I have gotten was manipulating the 'navigationSplitViewColumnWidth' but that always results in the view instantly appearing / disappearing. I am using SwiftUI for a MacOS specific app. Here is just a general idea of what I am currently doing, it is by no means a reflection of my real code but serves the purpose of this example. struct ContentView: View { @State private var columnWidth: CGFloat = 300 var body: some View { NavigationSplitView { List { NavigationLink(destination: DetailView(item: "Item 1")) { Text("Item 1") } NavigationLink(destination: DetailView(item: "Item 2")) { Text("Item 2") } NavigationLink(destination: DetailView(item: "Item 3")) { Text("Item 3") } } .navigationTitle("Items") } detail: { VStack { DetailView(item: "Select an item") Button(action: toggleColumnWidth) { Text(columnWidth == 300 ? "Collapse" : "Expand") } .padding() } } .navigationSplitViewColumnWidth(columnWidth) } private func toggleColumnWidth() { withAnimation { columnWidth = columnWidth == 300 ? 0 : 300 } } } struct DetailView: View { var item: String var body: some View { Text("Detail view for \(item)") .navigationTitle(item) .padding() } } @main struct MyApp: App { var body: some Scene { WindowGroup { ContentView() } } }
1
0
610
Jun ’24
SwiftData persistence between devices
Hello, I have a rudimentary list app that I have started, I am trying to establish a persistent sync with the iOS to the watch app. I am using swift data and have plans to use CloudKit too eventually. I made sure to recreate my data models and have them target both projects, but they only physically exist in the iOS folder. // Models: import Foundation import SwiftData @Model class GroceryListModel { @Attribute(.unique) var id: String var title: String var createdAt: Date @Relationship var items: [GroceryItemModel] init(id: String, title: String, createdAt: Date, items: [GroceryItemModel] ) { self.id = id self.title = title self.createdAt = createdAt self.items = items } } import Foundation import SwiftData @Model class GroceryItemModel { @Attribute(.unique) var id: UUID var name: String var quantity: Int // @Relationship var groceryList: [GroceryList] init(id: UUID, name: String, quantity: Int) { self.id = id self.name = name self.quantity = quantity } } // for iOS, how I create an item: // // AddGroceryListView.swift // Kitchen_Sync // // import SwiftUI import SwiftData struct AddGroceryListView: View { // Link to the persisted location @Environment(\.modelContext) private var context // Search & sort data @Query(sort: \.id, order: .forward) var allItems: [GroceryItemModel] // Props @State private var title = "" @State private var location = "" // Render view var body: some View { // provide text fields to enter title and location, and a button to add the list Text("Title: ") Button("Save") { createList() } } // Creates persisted item for list func createList() { let list = GroceryListModel(id: UUID().uuidString, title: "blah", createdAt: .now, items: allItems ) context.insert(list) try? context.save() } } #Preview { AddGroceryListView() } // for Apple Watch version: import SwiftUI import SwiftData struct GroceryListView: View { @Environment(\.modelContext) private var context @Query(sort: \.createdAt, order: .forward) var allGroceryLists: [GroceryListModel] var body: some View { // display list items and provide option to add new items Text("Grocery List View") ScrollView { VStack { ForEach(allGroceryLists) { item in Text("an item") } } } } } #Preview { GroceryListView() } // main app level for iOS: // // Kitchen_SyncApp.swift // Kitchen_Sync // // import SwiftUI import SwiftData @main struct Kitchen_SyncApp: App { var body: some Scene { WindowGroup { TabView { groceryListView groceryAddListView } .modelContainer(for: [ GroceryListModel.self, GroceryItemModel.self ]) } } var groceryListView: some View { NavigationStack { GroceryListView() .navigationTitle("List") } .tabItem { Label("List", systemImage: "list.bullet.indent") } } var groceryAddListView: some View { NavigationStack { AddGroceryListView() .navigationTitle("Add") } .tabItem { Label("Add", systemImage: "plus") } } } //#Preview { // Kitchen_SyncApp() //} // Main app for watch: // // Kitchen_SyncApp.swift // Kitchen_Sync Watch App // // import SwiftUI import SwiftData @main struct Kitchen_SyncWatchApp: App { var body: some Scene { WindowGroup { TabView { groceryListView } .modelContainer(for: [ GroceryListModel.self, GroceryItemModel.self ]) } } var groceryListView: some View { NavigationView { GroceryListView() .navigationTitle("List") } .tabItem { Label("List", systemImage: "list.bullet") } } }
1
0
588
Jun ’23